<?if(!defined("PROLOG_INCLUDED") || PROLOG_INCLUDED!==true)die();
    /**
     * Показать системную панель
     * @return html
     */
	function ShowPanel() {
		return Face::EditorPanel($_SERVER['PHP_SELF']);
	}

    /**
     * Задать <title>
     * @global array $arMeta
     * @param string $title
     * @return array
     */
    function SetTitle($title) {
        global $arMeta;
        return $arMeta["TITLE"] = $title;
    }

    /**
     * Задать <description>
     * @global array $arMeta
     * @param string $descr
     * @return array
     */
    function SetDescr($descr) {
        global $arMeta;
        return $arMeta["DESCRIPTION"] = $descr;
    }

    /**
     * Задать любое META-свойство
     * @global array $arMeta
     * @param string $key
     * @param string $value
     * @return array
     */
    function SetProperty($key, $value) {
        global $arMeta;
        return $arMeta[$key] = $value;
    }

    /**
     * Получить ИМЯ сайта
     * @global array $_CONFIG
     * @return array
     */
	function GetSiteName() {
		global $_CONFIG;
		return $_CONFIG["SITE_NAME"];
	}

    /**
     * Получить ОПИСАНИЕ сайта
     * @global array $_CONFIG
     * @return array
     */
	function GetSiteDescr() {
		global $_CONFIG;
		return $_CONFIG["SITE_DESCRIPTION"];
	}

    /**
     * Получить <title>
     * @global array $arMeta
     * @param bool $bOriginal
     * @return array
     */
    function GetTitle($bOriginal = false) {
    	global $arMeta;
		if ($bOriginal) {
			return $arMeta["TITLE"];
		}
    	return TV_PREPEND.'TITLE'.TV_APPEND;
    }

    /**
     * Получить <description>
     * @global array $arMeta
     * @return array
     */
    function GetDescr() {
        global $arMeta;
        return $arMeta["DESCRIPTION"];
    }

    /**
     * Получить любое свойство заданное SetProperty()
     * @global array $arMeta
     * @param string $property
     * @return array
     */
    function GetProperty($property) {
        global $arMeta;
        return $arMeta[$property];
    }

    /**
     * Задать модификатор текста по парам: $key => $value
     * @global array $arTV
     * @param string $key
     * @param string $value
     * @return array
     */
    function TextModifier($key, $value) {
        global $arTV;
        return $arTV[$key] = $value;
    }

    /**
     * Получить путь до текущей директории относительно корня сайта
     * @return string путь
     */
    function GetCurDir() {
        return substr($_SERVER["PHP_SELF"], 0, strrpos($_SERVER["PHP_SELF"], "/") + 1);
    }

    /**
     * Получить путь до текущей директории относительно DOCUMENT_ROOT
     * @return string путь
     */
    function GetCurPath() {
        return  $_SERVER["DOCUMENT_ROOT"].parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
    }

    /**
     * Получить путь до текущей страницы относительно корня сайта
     * @return string путь
     */
    function GetCurPage() {
        return $_SERVER["PHP_SELF"];
    }

    /**
     * Добавить сообщение для вывода пользователю в дальнейшем с помощью ShowMsg()
     * @param string $sMsg
     */
    function AddMsg($sMsg = "") {
    	$_SESSION["MESSAGE"] = $sMsg;
    }

    /**
     * Вывод сообщения пользователю, добавленного с помощью функции AddMsg()
     * @param string $sMsg
     * @param bool $bEcho
     * @return string
     */
    function ShowMsg($sMsg = "", $bEcho = true) {
    	if (!empty($sMsg)) {
    		$msgText = $sMsg;
    	} elseif (isset($_SESSION["MESSAGE"]) AND !empty($_SESSION["MESSAGE"])) {
    		$msgText = $_SESSION["MESSAGE"];
			unset($_SESSION["MESSAGE"]);
    	} else {
    		return '';
    	}
    	$str = '<div class="msg">';
    	$str .= $msgText;
    	$str .= '</div>';
		if ($bEcho) {
			echo $str;
		}
		return $str;
    }

    /**
     * Вывод сообщений об ошибке пользователю
     * @param array $arErrors
     * @param bool $bEcho
     * @return string
     */
    function ShowError($arErrors, $bEcho = true) {
    	$str = '<div class="error">';
    	if (!empty($arErrors) AND is_array($arErrors)) {
	    	$str .= join('<br />' ,$arErrors);
    	} elseif (!empty($arErrors)) {
    		$str .= $arErrors;
    	} else {
    		return '';
    	}
    	$str .= '</div>';
		if ($bEcho) {
			echo $str;
		}
	    return $str;
    }

    /**
     *
     * @param string $url
     * @param int $timeOut в секундах
     * @param bool $bJS
     * @return string | bool
     */
    function RedirectTo($url, $timeOut = 0, $bJS = false) {
    	if (!empty($url) AND $timeOut == 0) {
    		header('Location: '.$url);
    	} elseif (!empty($url) AND $timeOut == 0 AND !$bJS) {
            header('refresh:'.$timeOut.';url='.$url);
        } elseif (!empty($url) AND $timeOut > 0 AND $bJS) {
    		$js  = '<script type="text/javascript">';
    		$js .= 'RedirectTo("' . $url . '", ' . $timeOut . '000);';
    		$js .= '</script>';
    		echo $js;
    	} else {
    		return false;
    	}
    }

    /**
     * Получить путь, подставив в него значения вместо #ключей#
     * @param string $sTpl
     * @param array $arData
     * @return string
     */
    function GetStrTpl($sTpl, $arData) {
    	foreach ($arData as $field => $text) {
    		$arFromStr[] = '#'.$field.'#';
    		$arToStr[] = $text;
    	}
    	return str_replace($arFromStr, $arToStr, $sTpl);
    }

	/**
     * Дополнить массив безопасными данными, оригинальные значения с "~" ключами
     * @param array $arRes
     * @return array
     */
	function TildaArray($arRes) {
		$arTilda = array();
		foreach($arRes as $FName=>$arFValue) {
			if(is_array($arFValue))
				$arTilda[$FName] = htmlspecialcharsEx($arFValue);
			elseif(preg_match("/[;&<>\"]/", $arFValue))
				$arTilda[$FName] = htmlspecialcharsEx($arFValue);
			else
				$arTilda[$FName] = $arFValue;
			$arTilda["~".$FName] = $arFValue;
		}
		return $arTilda;
	}

    /**
     * Экранирование строки
     * @staticvar array $search
     * @staticvar array $replace
     * @param string $str
     * @return string
     */
	function htmlspecialcharsEx($str) {
		static $search = array("&amp;","&lt;","&gt;","&quot;","<",">","\"");
		static $replace = array("&amp;amp;","&amp;lt;","&amp;gt;","&amp;quot;","&lt;","&gt;","&quot;");
		return str_replace($search, $replace, $str);
	}

    /**
     * Убрать экранирование из строки
     * @param string $str
     * @return string
     */
	function htmlspecialcharsback($str) {
		if(strlen($str)>0) {
			$str = str_replace("&lt;", "<", $str);
			$str = str_replace("&gt;", ">", $str);
			$str = str_replace("&quot;", "\"", $str);
			$str = str_replace("&amp;", "&", $str);
		}
		return $str;
	}

    /**
     * Обрезать текст до нужной длинны
     * @param <type> $strText
     * @param <type> $intLen
     * @return <type>
     */
	function TruncateText($strText, $intLen, $sEnd = "") {
		if(strlen($strText) >= $intLen )
			return substr($strText, 0, $intLen).$sEnd;
		else
			return $strText;
	}

    /**
     * Подключение модуля
     * @global object $SYS
     * @param string $moduleName
     */
	function IncludeModule($moduleName) {
		global $SYS;
        // TODO: переделать под новую модель
		$SYS->IncludeModule($moduleName);
	}

    /**
     * Склеить массив в SQL-выражение
     * @param array $array
     * @param string $MODE
     * @param array $arTables
     * @return string
     */
	function glueArraySql($array, $MODE = "F", $arTables = false) {
		switch ($MODE) {
			case "I":
				$cntKey = 0;
				$cntVal = 0;

				foreach($array as $key => $value) {
					if ($value == "") {
						unset($array[$key]);
					}
				}

				$str = "(";
				foreach($array as $key => $value) {
					$cntKey++;
					$str .= sSql($key);
					if($cntKey != count($array)) {
						$str .= ", ";
					}
				}
				$str .= ") VALUES (";
				
				foreach($array as $key => $value) {
					$cntVal++;
					$str .= "'".sSql($value)."'";
					if($cntVal != count($array)) {
						$str .= ", ";
					}
				}
				$str .= ")";
				break;
			case "F":
				$cnt = 0;
				foreach($array as $key => $value) {
					$cnt++;
					$bTbl = false;
					if($arTables AND is_array($arTables)) {
						foreach($arTables as $t => $v) {
							if(strstr($value, $t.'.'))
								$bTbl = true;
						}
					}
					if($arTables AND $bTbl)
						$str .= sSql($key)." = ".sSql($value);
					else
						$str .= sSql($key)." = '".sSql($value)."'";
						
					if($cnt != count($array)) {
						if (is_array($arTables)) {
							$str .= " AND ";
						} else {
							$str .= ", ";
						}
					}
				}
				break;
			case "S":
			default:
				$cnt = 0;
				foreach($array as $value) {
					$cnt++;
					$str .= sSql($value);
					if($cnt != count($array)) {
						$str .= ", ";
					}
				}
				break;
		}
		return $str;
	}

    /**
     * Очистка массива с фильтром
     * @param array $arFilter
     * @return array
     * @todo Переписать или удалить
     */
	function filterClear($arFilter) {
		foreach($arFilter as $key => $value) {
			if (substr($key, 0, 8) == 'CATALOG.') {
				unset($arFilter[$key]);
			}
			if(substr($key, 0, 8) == 'ELEMENT.') {
				unset($arFilter[$key]);
				$arFilter[str_replace('ELEMENT.', '', $key)] = $value;
			}
		}
		return $arFilter;
	}

    /**
     * Склеить из массива SQL-выражение для фильтра
     * @param array $arFilter
     * @param array $arTables
     * @return string
     */
	function filterGlue($arFilter, $arTables = false) {
		//d($arFilter);
		$cnt = 0;
		$str = '';
		$signs = Array('=', '!', '!=', '<', '>', '<=', '>=');

		if(is_array($arFilter['CATALOG_ID']) AND !empty($arFilter['CATALOG_ID'])) {
			$arCatalogIDs = $arFilter['CATALOG_ID'];
			unset($arFilter['CATALOG_ID']);
		}

		foreach($arFilter as $key => $value) {
			if ($value == "" AND !in_array($key, $signs)) {
				unset($arFilter[$key]);
			}
		}

		foreach($arFilter as $key => $value) {
			$cnt++;
			$sign = getSign($key);
			$key = str_replace($signs, '', $key);
			$arConstants = Array("NULL", "null", "FALSE", "false", "TRUE", "true");
			if ($value === "NULL" OR $value === "null") {
				switch ($sign) {
					case '=':
						$sign = 'IS';
						break;
					case '!=':
						$sign = 'IS NOT';
						break;
					default:
						$sign = $sign;
						break;
				}
			}

			$bTbl = false;
			if($arTables AND is_array($arTables)) {
				foreach($arTables as $t => $v) {
					if(strstr($value, $t.'.'))
						$bTbl = true;
				}
			}
			if(($arTables AND $bTbl) OR in_array($value, $arConstants))
				$str .= sSql($key)." ".$sign." ".sSql($value);
			else
				$str .= sSql($key)." ".$sign." '".sSql($value)."'";

			if($cnt != count($arFilter)) {
				$str .= " AND ";
			}
		}

		if (is_array($arCatalogIDs) AND !empty($arCatalogIDs)) {
			if (!empty($str)) {
				$str .= " AND";
			}
			$str .= " (";
			$cntr = 1;
			foreach($arCatalogIDs as $catID) {
				if ($arTables === false) {
					$str .= "CATALOG_ID = '" . intVal($catID) . "'";
				} else {
					$str .= "ELEMENT.CATALOG_ID = '" . intVal($catID) . "'";
				}
				if($cntr != count($arCatalogIDs)) {
					$str .= " OR ";
					$cntr++;
				}
			}
			$str .= ') GROUP BY ';
			if ($arTables === false) {
				$str .= "ID";
			} else {
				$str .= "ELEMENT.ID";
			}
		}
		return $str;
	}

    /**
     * Преобразование знака ключа массива для фильтра в SQL-условие
     * @param string $key
     * @return string
     */
	function getSign($key) {
		switch ($key) {
			case strstr($key, '!'):
				$sign = '!=';
				break;
			case strstr($key, '>'):
				$sign = '>';
				break;
			case strstr($key, '>='):
				$sign = '>=';
				break;
			case strstr($key, '<'):
				$sign = '<';
				break;
			case strstr($key, '<='):
				$sign = '<=';
				break;
			default:
				$sign = '=';
				break;
		}
		return $sign;
	}

    /**
     * Преобразование массива $aOrder в SQL-выражение для сортировки
     * @param array $arOrder
     * @return string
     */
	function getOrderSql($arOrder) {
		$str = "";
		$str .= " ORDER BY ";
		$cnt = 0;
		foreach ($arOrder as $key => $value) {
			$cnt++;
			$str .= $key." ".$value;
			if($cnt != count($arOrder)) {
				$str .= ", ";
			}
		}
		return $str;
	}

    /**
     * Преобразование массива $arLimit в SQL-выражение для ограничение количества строк результата
     * @param array $arLimit
     * @return string
     */
	function getLimitSql($arLimit) {
		$str = " LIMIT ";
		if($arLimit["COUNT"] > 0 AND isset($arLimit["OFFSET"])) {
			$str .= $arLimit["COUNT"] . ' OFFSET ' . $arLimit["OFFSET"];
		} else {
			if(!isset($arLimit["PAGE"]) OR empty($arLimit["PAGE"])) {
				$page = "";
			} else {
				$page = $arLimit["COUNT"]*$arLimit["PAGE"].", ";
			}

			$str .= $page.$arLimit["COUNT"];
		}
		return $str;
	}

    /**
     * Генерация префикса SQL-выражения для добавления (INSERT) записи в БД
     * @param string $table
     * @param array $arFields
     * @return string
     */
	function addSql($table, $arFields) {
		$sql = "INSERT INTO ".$table." ";
		$sql .= glueArraySql($arFields, "I").";";
		return $sql;
	}

    /**
     * Генерация префикса SQL-выражения для обновления (UPDATE) записи в БД
     * @param string $table
     * @param array $arFields
     * @return string
     */
	function updSql($table, $arFields) {
		$sql = "UPDATE ".$table." SET ";
		$sql .= glueArraySql($arFields, "F")."";
		return $sql;
	}

    /**
     * Генерация SQL-выражения из массивов
     * @param array $arTables
     * @param string $arOrder
     * @param array $arFilter
     * @param string $arSelect
     * @param array $arLimit
     * @return string
     */
	function getListSql($arTables, $arOrder = Array(), $arFilter = Array(), $arSelect = Array(),  $arLimit = Array()) {
		// Таблицы
		$table = "";
		if(is_array($arTables)) {
			if(!empty($arTables)) {
				$cntTbl = 0;
				foreach($arTables as $tableAlias => $tableName) {
					$cntTbl++;
					$table .= " ".$tableName." as ".$tableAlias;
					if($cntTbl < count($arTables)) {
						$table .= ", ";
					}
				}
			} else {
				return false;
			}
		} else {
			if(!empty($arTables)) {
				$table = $arTables;
			} else {
				return false;
			}

		}

		// Порядок
		if(!$arOrder OR empty($arOrder)) {
			$arOrder = Array("SORT" => "ASC");
		}
		$order = getOrderSql($arOrder);

		// Выборка
		if(!$arSelect OR empty($arSelect)) {
			if(count($arTables) > 1) {
				$select = "DISTINCT *";
			} else {
				$select = "*";
			}
		} elseif($arSelect = "**") {
			$select = "DISTINCT *";
		} else {
			$select = glueArraySql($arSelect, "S");
		}

		// Фильтр
		if(!$arFilter OR empty($arFilter)) {
			$where = "";
		} else {
			$where = "WHERE ";
			$where .= filterGlue($arFilter, $arTables);
		}

		// Лимит
		if(!$arLimit) {
			$limit = "";
		} else {
			$limit = getLimitSql($arLimit);
		}

		$sql =  "SELECT " . $select . " FROM " . $table ." ". $where . $order . $limit . ";";
		return $sql;
	}

/**
     * Получить путь, подставив в него значения вместо #ключей#
     * @param string $str
     * @param array $arVariables
     * @return string
     * @todo Удалить
     */
	function getMsg($arVariables, $str) {
		foreach($arVariables as $var => $val) {
			$arVars[] = "#" . $var . "#";
			$arVals[] = $val;
		}
		return str_replace($arVars, $arVals, $str);
	}

    /**
     * Вывод сообщения об ошибке БД
     * @param string $msg
     * @todo переделать
     */
	function dbError($msg) {
		d("Ошибка SQL: ".$msg);
	}

    /**
     * Получить случайное значение строки
     * @param int $count
     * @return string
     */
	mt_srand(((double)microtime()*1000000) ^ crc32(uniqid('', true)));
	function GetRandom($count = 8) {
		$arSymbols = "abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ0123456789";
		$max = strlen($arSymbols)-1;
		$rand = '';
		for ($i=0; $i < $count; $i++) {
			$rand .= $arSymbols[mt_rand(0, $max)];
		}
		return $rand;
	}

    /**
     * Экранирование строк перед запросами к БД
     * @param string $strValue
     * @return string
     */
	function sSql($strValue) {
		if( PHP_REAL_ESCAPE_STRING_EXISTS ) { // PHP v4.3.0 or higher
			// undo any magic quote effects so mysql_real_escape_string can do the work
			if( PHP_MAGIC_QUOTES_ACTIVE ) { $strValue = stripslashes( $strValue ); }
			$strValue = mysql_real_escape_string( $strValue );
		} else { // before PHP v4.3.0
			// if magic quotes aren't already on then add slashes manually
			if( !PHP_MAGIC_QUOTES_ACTIVE ) { $strValue = addslashes( $strValue ); }
			// if magic quotes are active, then the slashes already exist
		}
		return $strValue;
	}

    /**
     * Экраниварование строк от XSS
     * @param string $str
     * @return string
     */
	function sXss($str) {
		return $str;
	}

	/**
     * Отладка
     * @param mixed $mixed
     * @param bool $showHidder
     * @param string $nameStr 
     */
    function d($mixed = "", $bShowHidder = false, $nameStr = "") {
		if($bShowHidder) {
			$elemId = 'arResult'.rand(123, 31337);
			if(!empty($nameStr)) {
				$elemName = $nameStr;
			} else {
				$elemName = $elemId;
			}
			echo '<a href="javascript:void(0)" onclick="document.getElementById(\''.$elemId.'\').style.display = (document.getElementById(\''.$elemId.'\').style.display == \'none\')?\'block\':\'none\'">'.$elemName.'</a>
	<div id="'.$elemId.'" style="display:none; background-color: #b1cdef">';
		}
		echo '<pre>';
		print_r($mixed);
		echo '</pre>';

		if ($bShowHidder) {
			echo '</div>';
		}
	}
    
?>